from typing import List

from .trd_level import Country, State, City, Date, CustomerCategory, CustomerLevel, PriceAdjustRule, Shipper, Courier, ValueAdded, Aging, CountryGroup, RpBookTime, RpCourierPostalOutlet, Currency, UomUom, Item, RPSalePriceAdjust
from pydantic import BaseModel, Field, root_validator
from functional import seq

"""
Config
"""


class Language(BaseModel):
    """
    语言表
    """
    id: int = Field(None, description='ID', gt=0)
    name: str = Field(None, description='说明', example='简体中文')
    code: str = Field(None, description='地区代码', example='zh_CN')

    @root_validator(pre=True)
    def create(cls, values):
        """ 传入res.lang的记录 """
        mdl = values.get('__from_odoo')
        env = values.get('__env')
        if mdl and env:
            values['id'] = mdl.id
            values['name'] = mdl.name
            values['code'] = mdl.code
        return values


"""
Primary
"""


class PostCode(BaseModel):
    """
    对应 【rp.post.code】  邮编
    """
    id: int = Field(None, description='邮编ID')
    name: str = Field(None, description='邮编名称')
    city: City = Field(None, description='市')
    state: State = Field(None, description='省')
    country_id: Country = Field(None, description='国家')
    level: str = Field(None, description='级别')

    @root_validator(pre=True)
    def create(cls, values):
        mdl = values.get('__from_odoo')
        env = values.get('__env')
        if mdl and env:
            values['id'] = mdl.id
            values['name'] = mdl.name
            values['city'] = City(__from_odoo=mdl.city_id, __env=env)
            values['state'] = State(__from_odoo=mdl.state_id, __env=env)
            values['country_id'] = Country(__from_odoo=mdl.country_id, __env=env)
            values['level'] = mdl.level
        return values


class MailRoute(BaseModel):
    """
    对应【rp.shipper.mail.route】邮路（托运商）
    """
    id: int = Field(None, description='邮路ID')
    shipper_info: Shipper = Field(None, description='托运商')
    courier_info: Courier = Field(None, description='承运商')
    name: str = Field(None, description='邮路名称')
    code: str = Field(None, description='邮路编码')
    value_added_list: List[ValueAdded] = Field(None, description='增值服务')
    aging_info: List[Aging] = Field(None, description='时效')
    from_groups: List[CountryGroup] = Field(None, description='起始地')
    to_groups: List[CountryGroup] = Field(None, description='目的地')

    @root_validator(pre=True)
    def create(cls, values):
        mdl = values.get('__from_odoo')
        env = values.get('__env')
        if mdl and env:
            values['shipper_info'] = Shipper(__from_odoo=mdl.shipper_id, __env=env)
            values['courier_info'] = Courier(__from_odoo=mdl.courier_id, __env=env)
            values['id'] = mdl.id
            values['name'] = mdl.name
            values['code'] = mdl.code
            values['value_added_list'] = [ValueAdded(__from_odoo=added, __env=env) for added in mdl.value_added_ids]
            values['aging_info'] = [Aging(__from_odoo=record, __env=env) for record in mdl.aging_ids]
            values['from_groups'] = [CountryGroup(__from_odoo=record, __env=env) for record in mdl.ship_from_country_group_ids]
            values['to_groups'] = [CountryGroup(__from_odoo=record, __env=env) for record in mdl.ship_to_country_group_ids]
        return values


class HeadTailFulfillment(BaseModel):
    """
    对应【rp.ship.order.fulfillment.line】头尾程明细
    """
    name: str = Field(None, description='名称')
    operation_type: str = Field(None, description='类型')
    book_date: Date = Field(None, description='预约时间')
    book_time_id: RpBookTime = Field(None, description='预约时段')
    postal_outlet_id: RpCourierPostalOutlet = Field(None, description='网点')

    @root_validator(pre=True)
    def create(cls, values):
        mdl = values.get('__from_odoo')
        env = values.get('__env')
        if mdl and env:
            values['name'] = mdl.name
            values['operation_type'] = mdl.operation_type
            values['book_time_id'] = RpBookTime(__from_odoo=mdl.book_time_id, __env=env)
            # values['postal_outlet_id'] = RpCourierPostalOutlet(__from_odoo=mdl.postal_outlet_id, __env=env)
        return values


class ShipValueAdded(BaseModel):
    """
    对应【rp.ship.order.value.added.line】订单增值服务明细
    """
    id: int = Field(None, description='订单增值服务ID')
    currency_id: Currency = Field(None, description='货币单位')
    value_added: ValueAdded = Field(None, description='增值服务')
    value_added_type: str = Field(None, description='类型')
    value_added_category: str = Field(None, description='增值服务等级')
    tag_price: float = Field(None, description='标价')
    sale_adjusted_price: float = Field(None, description='销售调后价')
    used_sale_price_adjust_ids: List[RPSalePriceAdjust] = Field(None, description='使用销售调价')
    actual_price: float = Field(None, description='实价')

    @root_validator(pre=True)
    def create(cls, values):
        mdl = values.get('__from_odoo')
        env = values.get('__env')
        if mdl and env:
            values['id'] = mdl.id
            values['currency_id'] = Currency(__from_odoo=mdl.currency_id, __env=env)
            values['value_added'] = ValueAdded(__from_odoo=mdl.value_added_id, __env=env)
            values['value_added_type'] = mdl.value_added_type
            values['value_added_category'] = mdl.value_added_category
            values['tag_price'] = mdl.tag_price
            values['sale_adjusted_price'] = mdl.sale_adjusted_price
            values['used_sale_price_adjust_ids'] = [RPSalePriceAdjust(__from_odoo=record, __env=env) for record in mdl.used_sale_price_adjust_ids]
            values['actual_price'] = mdl.actual_price
        return values


class RpShipmentValueAdded(BaseModel):
    """
    对应【rp.shipment.value.added.line】运输单增值服务明细
    """
    id: int = Field(None, description='增值服务明细ID')
    currency_id: Currency = Field(None, description='货币单位')
    value_added_id: ValueAdded = Field(None, description='增值服务')
    value_added_type: str = Field(None, description='类型')
    value_added_category: str = Field(None, description='增值服务等级')
    price: float = Field(None, description='价格')

    @root_validator(pre=True)
    def create(cls, values):
        mdl = values.get('__from_odoo')
        env = values.get('__env')
        if mdl and env:
            values['id'] = mdl.id
            values['currency_id'] = Currency(__from_odoo=mdl.currency_id, __env=env)
            values['value_added_id'] = ValueAdded(__from_odoo=mdl.value_added_id, __env=env)
            values['value_added_type'] = mdl.value_added_type
            values['value_added_category'] = mdl.value_added_category
            values['price'] = mdl.price
        return values


class Parcel(BaseModel):
    """
    对应【rp.parcel】 包裹
    """
    id: int = Field(None, description='包裹ID')
    code: str = Field(None, description='编码')
    weight: float = Field(None, description='重量')
    width: float = Field(None, description='宽度')
    height: float = Field(None, description='高度')
    long: float = Field(None, description='长度')
    volume_uom_id: UomUom = Field(None, description='体积单位')
    weight_uom_id: UomUom = Field(None, description='重量单位')
    weight_desc: str = Field(None, description='重量描述')
    volume_desc: str = Field(None, description='体积描述')
    desc: str = Field(None, description='描述')
    values: float = Field(None, description='总价值')
    item_details: List[Item] = Field(None, description='包裹明细')
    currency_id: Currency = Field(None, description='货币单位')
    package_photo_ids: List[str] = Field(None, description='包裹图片')

    @root_validator(pre=True)
    def create(cls, values):
        mdl = values.get('__from_odoo')
        env = values.get('__env')
        if mdl and env:
            values['id'] = mdl.id
            values['code'] = mdl.code
            values['weight'] = mdl.weight
            values['width'] = mdl.width
            values['height'] = mdl.height
            values['long'] = mdl.depth
            values['volume_uom_id'] = UomUom(__from_odoo=mdl.volume_uom_id, __env=env)
            values['weight_uom_id'] = UomUom(__from_odoo=mdl.weight_uom_id, __env=env)
            values['weight_desc'] = mdl.weight_desc
            values['volume_desc'] = mdl.volume_desc
            values['desc'] = mdl.desc
            values['values'] = mdl.values
            values['currency_id'] = Currency(__from_odoo=mdl.currency_id, __env=env)
            values['package_photo_ids'] = seq(mdl.package_photo_ids.ids).map(lambda r: f"https://localhost:8080/web/image?model=rp.parcel&id={r.id}&field=photo").to_list()
        return values


class Customer(BaseModel):
    """
    客户
    """
    id: int = Field(None, description='客户ID')
    name: str = Field(None, description='名称')
    email: str = Field(None, description='邮箱')

    @root_validator(pre=True)
    def create(cls, values):
        mdl = values.get('__from_odoo')
        env = values.get('__env')
        if mdl and env:
            values['id'] = mdl.id
            values['name'] = mdl.name
            values['email'] = mdl.email
        return values


class User(Customer):
    """
    用户
    """
    area_code: str = Field(None, description='区号')
    phone_num: str = Field(None, description='手机号')
    birthday_date: str = Field(None, description='生日')
    source_type: str = Field(None, description='来源')
    customer_category: CustomerCategory = Field(None, description='客户分类')
    customer_level: CustomerLevel = Field(None, description='客户等级')

    @root_validator(pre=True)
    def create(cls, values):
        values = super().create(values)
        mdl = values.get('__from_odoo')
        env = values.get('__env')
        if mdl and env:
            values['area_code'] = mdl.area_code
            values['phone_num'] = mdl.phone_number
            values['birthday_date'] = mdl.birthday_date.strftime('%Y-%m-%d %H:%M:%S') if mdl.birthday_date else None
            values['source_type'] = mdl.source_type
            values['customer_category'] = CustomerCategory(__from_odoo=mdl.rp_customer_category, __env=env)
            values['customer_level'] = CustomerLevel(__from_odoo=mdl.customer_level, __env=env)
        return values


"""
网站管理Reference Model
"""


class ContactUsType(BaseModel):
    """
    联系我们类型
    """
    id: int = Field(None, description='ID', gt=0)
    name: str = Field(None, description='名称(translate)')

    @root_validator(pre=True)
    def create(cls, values):
        """ 传入pe.web.contact.us.type的记录 """
        mdl = values.get('__from_odoo')
        env = values.get('__env')
        if mdl and env:
            values['id'] = mdl.id
            values['name'] = mdl.name
        return values


class SuggestedReadingTime(BaseModel):
    """
    建议阅读时间
    """
    id: int = Field(None, description='ID', gt=0)
    name: str = Field(None, description='说明', example='简体中文')
    integer_form: int = Field(None, description='数字格式')
    uom: str = Field(None, description='数字格式单位')
    clock_form: str = Field(None, description='时钟格式')
    text_form: str = Field(None, description='文本格式')

    @root_validator(pre=True)
    def create(cls, values):
        """ 传入pe.suggested.reading.time的记录 """
        mdl = values.get('__from_odoo')
        env = values.get('__env')
        if mdl and env:
            values['id'] = mdl.id
            values['name'] = mdl.name
            values['integer_form'] = mdl.integer_form
            values['uom'] = mdl.time_uom_id.name
            values['clock_form'] = mdl.clock_form
            values['text_form'] = mdl.text_form
        return values


class WebArticleCategory(BaseModel):
    """
    文章分类
    """
    id: int = Field(None, description='ID', gt=0)
    name: str = Field(None, description='名称(translate)')
    desc: str = Field(None, description='描述')

    @root_validator(pre=True)
    def create(cls, values):
        """ 传入pe.web.article.category的记录 """
        mdl = values.get('__from_odoo')
        env = values.get('__env')
        if mdl and env:
            values['id'] = mdl.id
            values['name'] = mdl.name
            values['desc'] = mdl.desc if mdl.desc else None
        return values


class WebArticleIndustry(BaseModel):
    """
    文章行业
    """
    id: int = Field(None, description='ID', gt=0)
    name: str = Field(None, description='名称(translate)')
    desc: str = Field(None, description='描述')

    @root_validator(pre=True)
    def create(cls, values):
        """ 传入pe.web.article.industry的记录 """
        mdl = values.get('__from_odoo')
        env = values.get('__env')
        if mdl and env:
            values['id'] = mdl.id
            values['name'] = mdl.name
            values['desc'] = mdl.desc if mdl.desc else None
        return values


class WebArticleTag(BaseModel):
    """
    文章标签
    """
    id: int = Field(None, description='ID', gt=0)
    name: str = Field(None, description='名称(translate)')
    desc: str = Field(None, description='描述')

    @root_validator(pre=True)
    def create(cls, values):
        """ 传入pe.web.article.tag的记录 """
        mdl = values.get('__from_odoo')
        env = values.get('__env')
        if mdl and env:
            values['id'] = mdl.id
            values['name'] = mdl.name
            values['desc'] = mdl.desc if mdl.desc else None
        return values


class RpQuestionAndAnswerType(BaseModel):
    """
    Q&A问答类型
    """
    id: int = Field(None, description='ID', gt=0)
    name: str = Field(None, description='Q&A问答类型名称')

    @root_validator(pre=True)
    def create(cls, values):
        """传入rp.question.and.answer.type的记录"""
        mdl = values.get('__from_odoo')
        env = values.get('__env')
        if mdl and env:
            values['id'] = mdl.id
            values['name'] = mdl.name
        return values


class RpQuestionAnswerLevel(BaseModel):
    """
        Q&A问答等级
    """
    id: int = Field(None, description='ID', gt=0)
    name: str = Field(None, description='Q&A问答等级')

    @root_validator(pre=True)
    def create(cls, values):
        """
        传入pe.question.and.answer.level的记录
        """
        mdl = values.get('__from_odoo')
        env = values.get('__env')
        if mdl and env:
            values['id'] = mdl.id
            values['name'] = mdl.name
        return values
